package org.btik.redstone.led.listener;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import org.btik.redstone.led.entity.DevInfo;
import org.btik.redstone.led.sender.LightRawNbi;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.inventory.meta.ItemMeta;
import org.slf4j.Logger;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class RedStoneListener implements Listener {
    private final Logger log;

    private final LightRawNbi lightRawNbi;

    private final ConcurrentHashMap<BlockKey, DevInfo> devs = new ConcurrentHashMap<>();

    private final Set<String> devSet = Collections.newSetFromMap(new ConcurrentHashMap<>());

    public RedStoneListener(LightRawNbi lightRawNbi, Logger logger) {
        this.lightRawNbi = lightRawNbi;
        this.log = logger;
    }

    @EventHandler
    public void onRedStoneSignal(BlockRedstoneEvent event) {
        Block block = event.getBlock();
        DevInfo devInfo = devs.get(new BlockKey(block));
        int newCurrent = event.getNewCurrent();
        if (Objects.nonNull(devInfo)) {
            lightRawNbi.send(devInfo.snBytes(), newCurrent);
        }
    }

    @EventHandler
    public void regReDev(BlockPlaceEvent blockPlaceEvent) {

        ItemMeta itemInHand = blockPlaceEvent.getItemInHand().getItemMeta();
        if (!itemInHand.hasDisplayName()) {
            return;
        }
        Component component = itemInHand.displayName();
        if (!(component instanceof TextComponent)) {
            return;
        }
        String displayName = ((TextComponent) component).content();
        log.info("displayName  :" + displayName);
        if (displayName.startsWith("SN:")) {
            Block blockPlaced = blockPlaceEvent.getBlockPlaced();
            String sn = displayName.substring(3);
            if (devSet.contains(sn)) {
                return;
            }
            devSet.add(sn);
            devs.put(new BlockKey(blockPlaced), new DevInfo(sn, sn.getBytes(StandardCharsets.UTF_8)));
            log.info("regReDev  :" + sn);
        }

    }

    @EventHandler
    public void deRegDev(BlockBreakEvent event) {
        Block block = event.getBlock();
        DevInfo devInfo = devs.remove(new BlockKey(block));
        if (Objects.nonNull(devInfo)) {
            devSet.remove(devInfo.sn());
        }
    }
}
